Skip to content

Conversation

@nlynzaad
Copy link
Contributor

@nlynzaad nlynzaad commented Jan 19, 2026

This PR applies the same fix that was done in #6389 for Solid to React. As mentioned by @theoludwig in the comments this affects React as well and was missed by the tests.

This PR also updates and aligns the tests across React, Solid and Vue.

Summary by CodeRabbit

  • New Features

    • Added a toggle button across frameworks to show/hide the URL hash value and added two hash-enabled links (Unicode hash and "abc") on the special-chars route.
  • Bug Fixes

    • Refined link active-state handling to improve hash-based matching consistency across navigation and server renders.
  • Tests

    • Updated end-to-end tests to cover both hash links, the toggle interaction, and post-navigation hash content checks.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 19, 2026

📝 Walkthrough

Walkthrough

Adds a toggle-controlled conditional display of the current URL hash in React, Solid, and Vue starter routes, updates e2e tests to use two hash links and toggle before asserting the hash, and adjusts link active-evaluation logic in react-router and solid-router regarding hash handling.

Changes

Cohort / File(s) Summary
React route & tests
e2e/react-start/basic/src/routes/specialChars/hash.tsx, e2e/react-start/basic/tests/special-characters.spec.ts
Adds toggleHashValue state and toggle button to conditionally render location().hash; tests now use special-hash-link-1 and special-hash-link-2, click toggle-hash-button before reading hash, and switch some assertions to toContainClass.
Solid route & tests
e2e/solid-start/basic/src/routes/specialChars/hash.tsx, e2e/solid-start/basic/tests/special-characters.spec.ts
Replaces automatic hash syncing (createEffect) with a boolean toggle and button-driven conditional hash display; tests updated to reference -1/-2 links, toggle before asserting hash, and use toContainClass in class checks.
Vue route & tests
e2e/vue-start/basic/src/routes/specialChars/hash.tsx, e2e/vue-start/basic/tests/special-characters.spec.ts
Replaces function route with a defineComponent providing toggleHashValue and a toggle button to conditionally show the location hash; tests updated to use two hash links and toggle before reading the hash, with containment-based class assertions.
Route link entries
e2e/*/basic/src/routes/specialChars/route.tsx (React, Solid, Vue)
Renames original special-hash-linkspecial-hash-link-1 and adds special-hash-link-2 linking to same route with hash: 'abc' and includeHash: true; link labels updated (e.g., "Unicode Hash 대
React router link logic
packages/react-router/src/link.tsx
Introduces activeState via useRouterState and consumes it with useSyncExternalStore; adds server-aware snapshot logic to account for includeHash and _hash.
Solid router link logic
packages/solid-router/src/link.tsx
useLinkProps now evaluates hash comparison unconditionally when includeHash is set (removed prior server-only guard), causing hash comparison on both server and client.

Sequence Diagram(s)

(Skipped — changes are UI toggles and focused link logic updates that do not introduce a new multi-component sequential flow requiring visualization.)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

package: vue-router

Suggested reviewers

  • schiller-manuel

Poem

🐇 I nudge a little toggle, peek the hash so bright,
Unicode and "abc" pop into sight,
React, Solid, Vue — I hop with glee,
Links bold or quiet, what fun to see,
A rabbit cheers for code that's light!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: applying Link active properties correctly on SSR when including hash, which is the core fix across React, Solid, and Vue implementations.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud
Copy link

nx-cloud bot commented Jan 19, 2026

View your CI Pipeline Execution ↗ for commit 888749e

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ✅ Succeeded 12m 2s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 55s View ↗

☁️ Nx Cloud last updated this comment at 2026-01-21 00:50:23 UTC

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jan 19, 2026

More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/arktype-adapter@6421

@tanstack/eslint-plugin-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/eslint-plugin-router@6421

@tanstack/history

npm i https://pkg.pr.new/TanStack/router/@tanstack/history@6421

@tanstack/nitro-v2-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/nitro-v2-vite-plugin@6421

@tanstack/react-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router@6421

@tanstack/react-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-devtools@6421

@tanstack/react-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-ssr-query@6421

@tanstack/react-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start@6421

@tanstack/react-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-client@6421

@tanstack/react-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-server@6421

@tanstack/router-cli

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-cli@6421

@tanstack/router-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-core@6421

@tanstack/router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools@6421

@tanstack/router-devtools-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools-core@6421

@tanstack/router-generator

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-generator@6421

@tanstack/router-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-plugin@6421

@tanstack/router-ssr-query-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-ssr-query-core@6421

@tanstack/router-utils

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-utils@6421

@tanstack/router-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-vite-plugin@6421

@tanstack/solid-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router@6421

@tanstack/solid-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-devtools@6421

@tanstack/solid-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-ssr-query@6421

@tanstack/solid-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start@6421

@tanstack/solid-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-client@6421

@tanstack/solid-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-server@6421

@tanstack/start-client-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-client-core@6421

@tanstack/start-fn-stubs

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-fn-stubs@6421

@tanstack/start-plugin-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-plugin-core@6421

@tanstack/start-server-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-core@6421

@tanstack/start-static-server-functions

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-static-server-functions@6421

@tanstack/start-storage-context

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-storage-context@6421

@tanstack/valibot-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/valibot-adapter@6421

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/TanStack/router/@tanstack/virtual-file-routes@6421

@tanstack/vue-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router@6421

@tanstack/vue-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router-devtools@6421

@tanstack/vue-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router-ssr-query@6421

@tanstack/vue-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start@6421

@tanstack/vue-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start-client@6421

@tanstack/vue-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start-server@6421

@tanstack/zod-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/zod-adapter@6421

commit: 888749e

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@packages/react-router/src/link.tsx`:
- Around line 100-105: currentHash from useRouterState is subscribed but not
used, so hash-only navigations don't trigger recomputation of href; update the
memo dependencies (where buildLocation/_options/next/href are computed) to
include currentHash (or include currentHash in next's deps) so buildLocation is
re-run on hash changes and remove the unused-variable issue—locate the code that
computes next/_options/href (the memoized block that calls buildLocation) and
add currentHash to its dependency array.

@theoludwig
Copy link

theoludwig commented Jan 20, 2026

Thank you for working on this!

Edit: I tried to test the PR using pkg.pr.new with:

"@tanstack/react-router": "https://pkg.pr.new/TanStack/router/@tanstack/react-router@6421"
"@tanstack/react-start": "https://pkg.pr.new/TanStack/router/@tanstack/react-start@6421"

However, it doesn't seem to resolve the hydratation issue. And now all my links that point to the same page are considered "active", even with includeHash: true, and exact: true.

@nlynzaad nlynzaad marked this pull request as draft January 20, 2026 01:02
@nlynzaad
Copy link
Contributor Author

Thank you for working on this!

Edit: I tried to test the PR using pkg.pr.new with:

"@tanstack/react-router": "https://pkg.pr.new/TanStack/router/@tanstack/react-router@6421"
"@tanstack/react-start": "https://pkg.pr.new/TanStack/router/@tanstack/react-start@6421"

However, it doesn't seem to resolve the hydratation issue. And now all my links that point to the same page are considered "active", even with includeHash: true, and exact: true.

picked this up during testing and hence the draft status, digging through it to find a more holistic solution

@nlynzaad nlynzaad marked this pull request as ready for review January 21, 2026 00:28
@nlynzaad
Copy link
Contributor Author

@theoludwig could you test the latest builds and advise if the problem is resolved for you. When including hashes for active options you can remove exact:true as that overrides the hash checks.

@theoludwig
Copy link

theoludwig commented Jan 21, 2026

@theoludwig could you test the latest builds and advise if the problem is resolved for you. When including hashes for active options you can remove exact:true as that overrides the hash checks.

Oh indeed, the issue is now resolved! I needed to do rm -rf "$(pnpm store path)" otherwise pnpm wouldn't pick the change from pkg.pr.new.

I end up doing something like this for checking if it needs exact: true or includeHash: true:

const SidebarItemCreate = createLink(SidebarItemRaw)
export const SidebarItem: LinkComponent<React.FC<SidebarItemRawProps>> = (props) => {
  return (
    <SidebarItemCreate
      activeProps={{
        isActive: true,
      }}
      activeOptions={{
        exact: props.hash == null,
        includeHash: props.hash != null,
      }}
      {...props}
    />
  )
}

Thank you again! Looking forward to getting this released.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants